package org.zh.client.tra_ds;

import com.alibaba.druid.util.JdbcUtils;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import javax.sql.DataSource;
import java.sql.Connection;


@Component
@Aspect
public class ZHOpenTransactionAdvice {

    private final DataSource dataSource;

    public ZHOpenTransactionAdvice(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    @Pointcut("@annotation(org.zh.client.tra_ds.Transaction)")
    public void pointCutTX() {
    }

    @Around("pointCutTX()")
    public Object before(ProceedingJoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Transaction anno = signature.getMethod().getAnnotation(Transaction.class);
        Connection conn = null;
        try {
            if (anno.readOnly()) {
                conn = dataSource.getConnection();
                conn.setReadOnly(true);
                Object proceed = joinPoint.proceed();
                conn.setReadOnly(false);
                return proceed;
            } else {
                conn = dataSource.getConnection();
                conn.setAutoCommit(false);
                conn.setReadOnly(false);
                conn.setTransactionIsolation(anno.isolation().value());
                Object proceed = joinPoint.proceed();
                conn.commit();
                conn.setAutoCommit(true);
                conn.setTransactionIsolation(anno.isolation().value());
                return proceed;
            }
        } catch (Throwable e) {
            JdbcUtils.close(conn);
            throw new RuntimeException(e);
        } finally {
            JdbcUtils.close(conn);
        }
    }
}
